﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.IO;
using System.Reflection;
using Microsoft.Expression.Encoder.Plugins.Publishing;
using System.Xml;

namespace EncoderCmdlet
{
    /// <summary>
    /// Class that enables invocation of publish plugins
    /// </summary>
    [Cmdlet("Invoke", "Publish", SupportsShouldProcess = true)]
    public class InvokePublish : PSCmdlet
    {
        /// <summary>
        /// Name of Plugin
        /// </summary>
        [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage="You need to supply plugin")]
        [ValidateNotNullOrEmpty]
        public string Plugin
        {
            get;
            set;
        }

        /// <summary>
        /// Configuration file
        /// </summary>
        [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "You need to supply plugin")]
        [ValidateNotNullOrEmpty]
        public string Configuration
        {
            get;
            set;
        }

        /// <summary>
        /// Pipeline input
        /// </summary>
        [Alias("FullName")]
        [Parameter(ParameterSetName = "Objects", Mandatory = false, ValueFromPipelineByPropertyName = true)]
        [ValidateNotNullOrEmpty]
        public string Input
        {
            get;
            set;
        }

        /// <summary>
        /// Do the work
        /// </summary>
        protected override void ProcessRecord()
        {
            base.ProcessRecord();

            string pluginPath = Path.Combine(ProgramFilesx86(),@"Microsoft Expression\Encoder 3\Plugins");

            pluginPath = Path.Combine(pluginPath, Plugin);

            PublishPlugin publisher = null;

            if (File.Exists(pluginPath))
            {
                var plugin  = Assembly.LoadFrom(pluginPath);

                Type publisherType = FindPublisherType(plugin);
   
                publisher =
                    plugin.CreateInstance(publisherType.FullName) as PublishPlugin;

                publisher.ProgressEvent += new EventHandler<ProgressEventArgs>(publisher_ProgressEvent);
            }

            if (publisher!=null && Directory.Exists(Input))
            {

                using (MemoryStream ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(Configuration)))
                {
                    using (XmlReader xr = new XmlTextReader(ms))
                    {
                        publisher.LoadJobSettings(xr);
                        publisher.PerformPublish(Input, Directory.GetFiles(Input));
                    }
                }
            }
               
        }

        Type FindPublisherType(Assembly a)
        {
            var types = a.GetTypes();

            foreach (var type in types)
            {
                if (type.BaseType == typeof(PublishPlugin))
                {
                    return type;
                }
            }

            return null;
        }

        static string ProgramFilesx86() { if (8 == IntPtr.Size || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432")))) { return Environment.GetEnvironmentVariable("ProgramFiles(x86)"); } return Environment.GetEnvironmentVariable("ProgramFiles"); }

        void publisher_ProgressEvent(object sender, ProgressEventArgs e)
        {
            ProgressRecord record = new ProgressRecord(0, "Uploading.. ",e.Description);
            record.PercentComplete = Convert.ToInt32(e.Progress);
            WriteProgress(record);
        }

    }
}
